﻿using RotovapPlatform.Domain.Common;
using RotovapPlatform.Domain.Services.Data;

namespace RotovapPlatform.Application.Services.Data
{
	/// <summary>
	/// 数据记录应用服务接口
	/// 负责协调数据记录的应用层功能
	/// </summary>
	public interface IDataRecordingAppService
	{
		/// <summary>
		/// 获取设备参数历史记录
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <param name="startTime">开始时间</param>
		/// <param name="endTime">结束时间</param>
		/// <param name="interval">采样间隔（秒），用于数据降采样</param>
		/// <returns>设备参数历史记录</returns>
		Task<List<DeviceParameters>> GetDeviceParametersHistoryAsync(Guid? experimentId, DateTime startTime, DateTime endTime, int? interval = null);

		/// <summary>
		/// 获取实验状态历史记录
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <param name="startTime">开始时间</param>
		/// <param name="endTime">结束时间</param>
		/// <returns>实验状态历史记录</returns>
		Task<List<ExperimentStatusRecord>> GetExperimentStatusHistoryAsync(Guid experimentId, DateTime startTime, DateTime endTime);

		/// <summary>
		/// 获取实验结果
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>实验结果</returns>
		Task<ExperimentResult> GetExperimentResultAsync(Guid experimentId);

		/// <summary>
		/// 获取实验组结果
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		/// <returns>实验结果列表</returns>
		Task<List<ExperimentResult>> GetExperimentGroupResultsAsync(Guid experimentGroupId);

		/// <summary>
		/// 获取系统事件历史记录
		/// </summary>
		/// <param name="startTime">开始时间</param>
		/// <param name="endTime">结束时间</param>
		/// <param name="eventTypes">事件类型列表</param>
		/// <param name="severities">严重程度列表</param>
		/// <param name="pageIndex">页索引</param>
		/// <param name="pageSize">页大小</param>
		/// <returns>系统事件历史记录</returns>
		Task<PagedResult<SystemEvent>> GetSystemEventHistoryAsync(
			DateTime startTime,
			DateTime endTime,
			List<SystemEventType> eventTypes = null,
			List<EventSeverity> severities = null,
			int pageIndex = 0,
			int pageSize = 50);

		/// <summary>
		/// 获取报警历史记录
		/// </summary>
		/// <param name="startTime">开始时间</param>
		/// <param name="endTime">结束时间</param>
		/// <param name="alarmTypes">报警类型列表</param>
		/// <param name="severities">严重程度列表</param>
		/// <param name="includeAcknowledged">是否包含已确认的报警</param>
		/// <param name="pageIndex">页索引</param>
		/// <param name="pageSize">页大小</param>
		/// <returns>报警历史记录</returns>
		Task<PagedResult<AlarmRecord>> GetAlarmHistoryAsync(
			DateTime startTime,
			DateTime endTime,
			List<AlarmType> alarmTypes = null,
			List<AlarmSeverity> severities = null,
			bool includeAcknowledged = true,
			int pageIndex = 0,
			int pageSize = 50);

		/// <summary>
		/// 确认报警
		/// </summary>
		/// <param name="alarmId">报警ID</param>
		/// <param name="acknowledgedBy">确认用户</param>
		/// <param name="acknowledgementNotes">确认备注</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> AcknowledgeAlarmAsync(Guid alarmId, string acknowledgedBy, string acknowledgementNotes = null);

		/// <summary>
		/// 批量确认报警
		/// </summary>
		/// <param name="alarmIds">报警ID列表</param>
		/// <param name="acknowledgedBy">确认用户</param>
		/// <param name="acknowledgementNotes">确认备注</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> AcknowledgeAlarmsAsync(List<Guid> alarmIds, string acknowledgedBy, string acknowledgementNotes = null);

		/// <summary>
		/// 导出实验数据
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <param name="exportFormat">导出格式</param>
		/// <param name="filePath">文件路径</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExportExperimentDataAsync(Guid experimentId, ExportFormat exportFormat, string filePath);

		/// <summary>
		/// 导出实验组数据
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		/// <param name="exportFormat">导出格式</param>
		/// <param name="filePath">文件路径</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExportExperimentGroupDataAsync(Guid experimentGroupId, ExportFormat exportFormat, string filePath);

		/// <summary>
		/// 导出系统事件数据
		/// </summary>
		/// <param name="startTime">开始时间</param>
		/// <param name="endTime">结束时间</param>
		/// <param name="eventTypes">事件类型列表</param>
		/// <param name="exportFormat">导出格式</param>
		/// <param name="filePath">文件路径</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExportSystemEventDataAsync(
			DateTime startTime,
			DateTime endTime,
			List<SystemEventType> eventTypes,
			ExportFormat exportFormat,
			string filePath);

		/// <summary>
		/// 导出报警数据
		/// </summary>
		/// <param name="startTime">开始时间</param>
		/// <param name="endTime">结束时间</param>
		/// <param name="alarmTypes">报警类型列表</param>
		/// <param name="exportFormat">导出格式</param>
		/// <param name="filePath">文件路径</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExportAlarmDataAsync(
			DateTime startTime,
			DateTime endTime,
			List<AlarmType> alarmTypes,
			ExportFormat exportFormat,
			string filePath);

		/// <summary>
		/// 获取当前活跃报警
		/// </summary>
		/// <returns>活跃报警列表</returns>
		Task<List<AlarmRecord>> GetActiveAlarmsAsync();

		/// <summary>
		/// 获取实验数据统计
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>实验数据统计</returns>
		Task<ExperimentDataStatistics> GetExperimentDataStatisticsAsync(Guid experimentId);

		/// <summary>
		/// 获取实验组数据统计
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		/// <returns>实验组数据统计</returns>
		Task<ExperimentGroupDataStatistics> GetExperimentGroupDataStatisticsAsync(Guid experimentGroupId);

		/// <summary>
		/// 清理历史数据
		/// </summary>
		/// <param name="beforeDate">清理此日期之前的数据</param>
		/// <param name="dataTypes">数据类型列表</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> CleanupHistoricalDataAsync(DateTime beforeDate, List<DataType> dataTypes);

		/// <summary>
		/// 备份数据
		/// </summary>
		/// <param name="backupPath">备份路径</param>
		/// <param name="dataTypes">数据类型列表</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> BackupDataAsync(string backupPath, List<DataType> dataTypes);

		/// <summary>
		/// 恢复数据
		/// </summary>
		/// <param name="backupPath">备份路径</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> RestoreDataAsync(string backupPath);

		/// <summary>
		/// 注册报警回调
		/// </summary>
		/// <param name="callback">回调函数</param>
		void RegisterAlarmCallback(Func<AlarmRecord, Task> callback);
	}

	/// <summary>
	/// 分页结果
	/// </summary>
	/// <typeparam name="T">数据类型</typeparam>
	public class PagedResult<T>
	{
		/// <summary>
		/// 数据列表
		/// </summary>
		public List<T> Items { get; set; } = new List<T>();

		/// <summary>
		/// 总记录数
		/// </summary>
		public int TotalCount { get; set; }

		/// <summary>
		/// 页索引
		/// </summary>
		public int PageIndex { get; set; }

		/// <summary>
		/// 页大小
		/// </summary>
		public int PageSize { get; set; }

		/// <summary>
		/// 总页数
		/// </summary>
		public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);

		/// <summary>
		/// 是否有上一页
		/// </summary>
		public bool HasPreviousPage => PageIndex > 0;

		/// <summary>
		/// 是否有下一页
		/// </summary>
		public bool HasNextPage => PageIndex + 1 < TotalPages;
	}

	/// <summary>
	/// 实验数据统计
	/// </summary>
	public class ExperimentDataStatistics
	{
		/// <summary>
		/// 实验ID
		/// </summary>
		public Guid ExperimentId { get; set; }

		/// <summary>
		/// 实验名称
		/// </summary>
		public string ExperimentName { get; set; }

		/// <summary>
		/// 开始时间
		/// </summary>
		public DateTime? StartTime { get; set; }

		/// <summary>
		/// 结束时间
		/// </summary>
		public DateTime? EndTime { get; set; }

		/// <summary>
		/// 总执行时间（分钟）
		/// </summary>
		public double? TotalExecutionTimeMinutes { get; set; }

		/// <summary>
		/// 平均油浴温度
		/// </summary>
		public double? AverageOilBathTemperature { get; set; }

		/// <summary>
		/// 最大油浴温度
		/// </summary>
		public double? MaxOilBathTemperature { get; set; }

		/// <summary>
		/// 最小油浴温度
		/// </summary>
		public double? MinOilBathTemperature { get; set; }

		/// <summary>
		/// 平均冷凝温度
		/// </summary>
		public double? AverageCondensationTemperature { get; set; }

		/// <summary>
		/// 平均旋转速度
		/// </summary>
		public double? AverageRotationSpeed { get; set; }

		/// <summary>
		/// 平均真空度
		/// </summary>
		public double? AverageVacuum { get; set; }

		/// <summary>
		/// 产品收集量
		/// </summary>
		public double? ProductCollectionAmount { get; set; }

		/// <summary>
		/// 收率
		/// </summary>
		public double? Yield { get; set; }

		/// <summary>
		/// 报警次数
		/// </summary>
		public int AlarmCount { get; set; }

		/// <summary>
		/// 暂停次数
		/// </summary>
		public int PauseCount { get; set; }

		/// <summary>
		/// 其他统计数据
		/// </summary>
		public Dictionary<string, object> AdditionalStatistics { get; set; } = new Dictionary<string, object>();
	}

	/// <summary>
	/// 实验组数据统计
	/// </summary>
	public class ExperimentGroupDataStatistics
	{
		/// <summary>
		/// 实验组ID
		/// </summary>
		public Guid ExperimentGroupId { get; set; }

		/// <summary>
		/// 实验组名称
		/// </summary>
		public string ExperimentGroupName { get; set; }

		/// <summary>
		/// 实验数量
		/// </summary>
		public int ExperimentCount { get; set; }

		/// <summary>
		/// 成功实验数量
		/// </summary>
		public int SuccessfulExperimentCount { get; set; }

		/// <summary>
		/// 失败实验数量
		/// </summary>
		public int FailedExperimentCount { get; set; }

		/// <summary>
		/// 开始时间
		/// </summary>
		public DateTime? StartTime { get; set; }

		/// <summary>
		/// 结束时间
		/// </summary>
		public DateTime? EndTime { get; set; }

		/// <summary>
		/// 总执行时间（分钟）
		/// </summary>
		public double? TotalExecutionTimeMinutes { get; set; }

		/// <summary>
		/// 平均实验执行时间（分钟）
		/// </summary>
		public double? AverageExperimentExecutionTimeMinutes { get; set; }

		/// <summary>
		/// 平均收率
		/// </summary>
		public double? AverageYield { get; set; }

		/// <summary>
		/// 最高收率
		/// </summary>
		public double? MaxYield { get; set; }

		/// <summary>
		/// 最低收率
		/// </summary>
		public double? MinYield { get; set; }

		/// <summary>
		/// 总产品收集量
		/// </summary>
		public double? TotalProductCollectionAmount { get; set; }

		/// <summary>
		/// 报警次数
		/// </summary>
		public int AlarmCount { get; set; }

		/// <summary>
		/// 实验统计列表
		/// </summary>
		public List<ExperimentDataStatistics> ExperimentStatistics { get; set; } = new List<ExperimentDataStatistics>();

		/// <summary>
		/// 其他统计数据
		/// </summary>
		public Dictionary<string, object> AdditionalStatistics { get; set; } = new Dictionary<string, object>();
	}
}